package com.mxl.service.channel;

import java.io.UnsupportedEncodingException;
import java.sql.Timestamp;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.mxl.common.BeanConvertUtil;
import com.mxl.common.MD5Util;
import com.mxl.common.helper.InterfaceType;
import com.mxl.dao.channel.ChargeConfigDao;
import com.mxl.dao.channel.model.ChargeConfig;
import com.mxl.dao.channel.model.DealRequest;
import com.mxl.dao.channel.model.DealResponse;
import com.mxl.service.channel.strategy.RequestStrategyFactory;

/**
 * 
 * @author mxl
 * 
 */
@Service("dealRequestWrapper")
public class CommDealRequestWrapper implements DealRequestWrapper {
	private static Logger logger = LoggerFactory
			.getLogger(CommDealRequestWrapper.class);

	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

	@Resource(name = "chargeConfigDao")
	private ChargeConfigDao chargeConfigDao;

	@Resource(name = "requestStrategyFactory")
	private RequestStrategyFactory requestStrategyFactory;

	public void addRequestParameters(DealRequest request) {
		setChargeUrl(request, InterfaceType.REQUEST.getValue());
	}

	public void addQueryParameters(DealRequest request) {
		setChargeUrl(request, InterfaceType.QUERY.getValue());
	}

	private void setChargeUrl(DealRequest request, int interfaceType) {
		// 根据渠道查询相关信息
		String code = request.getChannelCode();
		ChargeConfig config = chargeConfigDao.queryByCode(
				code.substring(0, code.indexOf("-")), interfaceType);
		request.setNotifyUrl(config.getNotifyUrl());
		// 增加各渠道差别处理
		String chargeVerifyTemplate = config.getRequestSignTemplate();
		String[] args = config.getSidynamicsField().split(",");
		request.setSubmitDate(sdf.format(new Date()));
		beforHandelRequest(request, config);
		Map<String, String> map = BeanConvertUtil.bean2Map(request);
		// 处理金额为100.00格式
		// map.put("requestAmount", map.get("requestAmount") + ".00");
		// afterHandelRequest(map);
		String[] value = new String[args.length];
		for (int i = 0; i < args.length; i++) {
			value[i] = map.get(args[i]);
		}
		// 反射字段值
		String signO = MessageFormat.format(chargeVerifyTemplate, value);
		logger.info("CommDealRequestWrapper-signO-{},,{}", request.getSeqNo(),
				signO);

		if ("1".equals(config.getSignType())) {
			String signN = MD5Util.md5Hex(signO);
			logger.info("CommDealRequestWrapper-signN-{},,{}",
					request.getSeqNo(), signN);
			request.setSign(signN);
		}
		map = BeanConvertUtil.bean2Map(request);
		// afterHandelRequest(map);
		// map.put("requestAmount", map.get("requestAmount") + ".00");
		String r = config.getRequestTemplate();
		String rargs[] = config.getRedynamicsField().split(",");
		value = new String[rargs.length];
		for (int i = 0; i < rargs.length; i++) {
			value[i] = map.get(rargs[i]);
		}
		String requestN = MessageFormat.format(r, value);

		// 设置请求url
		request.setReqContentval(buildChargeUrl(config.getRequestUrl(),
				requestN));
	}

	private void beforHandelRequest(DealRequest request, ChargeConfig config) {
		requestStrategyFactory.handleRequest(request, config.getCardEncode());
	}

	public String buildChargeUrl(String url, String requestN) {
		StringBuilder builder = new StringBuilder(url);
		if (url.indexOf("?") > 0) {
			builder.append("&");
		} else {
			builder.append("?");
		}
		builder.append(requestN);
		return builder.toString();
	}

	public void resolveCardResponse(CommChargeResponse chargeResponse,
			byte[] chargeResult) {
		String resultCode = null;
		try {
			resultCode = new String(chargeResult, "UTF-8").trim();
			chargeResponse.setResultstr(resultCode);
			logger.info(" card charge response is : {}", resultCode);
		} catch (UnsupportedEncodingException e) {
			logger.info("UnsupportedEncodingException card charge response is",
					e);
		}
	}

	private void resolverReadTimeout(CommChargeResponse chargeResponse) {
		chargeResponse.setResultstr("999");

	}

	public void resolverTimeout(CommChargeResponse chargeResponse) {
		chargeResponse.setResultstr("999");

	}

	public DealResponse buildDealResponse(CommChargeResponse chargeResponse) {
		DealResponse dealResponse = new DealResponse();
		dealResponse.setCreationDate(new Timestamp(System.currentTimeMillis()));
		dealResponse.setResContentval(chargeResponse.getResultstr());
		return dealResponse;
	}
}
